package com.ruoyi.flow.auth.menu;

import com.ruoyi.flow.common.tools.filewatch.FileListener;
import com.ruoyi.flow.common.tools.filewatch.FileWatcher;
import com.ruoyi.flow.common.utils.XmlUtils;
import com.ruoyi.flow.auth.menu.Menu;
import com.google.common.collect.Lists;
import org.apache.commons.lang3.StringUtils;
import org.dom4j.Document;
import org.dom4j.Node;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.FilenameFilter;
import java.nio.file.Path;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @Author: wtian
 * @Description:
 * @Date: Created in 19:06 2018/8/9
 * @Version: 1.0
 */
public class MenuReader {
    private static final Logger LOGGER = LoggerFactory.getLogger(MenuReader.class);
    public static final String CONFIG_PATH = "/conf/admin/menus.xml";
    private static final ExecutorService singlePool = Executors.newSingleThreadExecutor();
    private List<com.ruoyi.flow.auth.menu.Menu> menus;

    private MenuReader() {
        read();
        singlePool.submit(new Runnable() {
            @Override
            public void run() {
                //检测文件被修改后，重新加载
                FileWatcher watcher = new FileWatcher(new File(MenuReader.class.getResource("/").getPath() + "/conf/admin").toPath(), new FilenameFilter() {
                    @Override
                    public boolean accept(File dir, String name) {
                        return StringUtils.equals(name, "menus.xml");
                    }
                }, new FileListener() {
                    @Override
                    public void onCreate(Path file) {

                    }

                    @Override
                    public void onModify(Path file) {//发现修改重新加载
                        LOGGER.info("监测到menus.xml被修改，重新加载menus.xml");
                        read();
                    }

                    @Override
                    public void onDelete(Path file) {
                        LOGGER.info("监测到menus.xml被删除");
                    }
                });
                watcher.watch();
            }
        });

    }

    private static final class SingleHolder {
        public static final MenuReader instance = new MenuReader();
    }

    public static final MenuReader getInstance() {
        return SingleHolder.instance;
    }

    private void read() {
        Document document = XmlUtils.parse(CONFIG_PATH);
        List<Node> menuNodes = XmlUtils.getChildren(document, "/menus/menu");
        List<com.ruoyi.flow.auth.menu.Menu> menus = Lists.newLinkedList();
        com.ruoyi.flow.auth.menu.Menu menu = null;
        for (Node menuNode : menuNodes) {
            Node nameNode = XmlUtils.getChild(menuNode, "name");
            Node iconNode = XmlUtils.getChild(menuNode, "icon");
            List<Node> subMenuNodes = XmlUtils.getChildren(menuNode, "subMenus/menu");
            menu = new com.ruoyi.flow.auth.menu.Menu(nameNode.getText(), iconNode.getText());
            if (subMenuNodes != null && !subMenuNodes.isEmpty()) {
                for (Node subMenuNode : subMenuNodes) {
                    Node subNameNode = XmlUtils.getChild(subMenuNode, "name");
                    Node subIconNode = XmlUtils.getChild(subMenuNode, "icon");
                    Node subUrlNode = XmlUtils.getChild(subMenuNode, "url");
                    com.ruoyi.flow.auth.menu.Menu subMenu = new com.ruoyi.flow.auth.menu.Menu(subUrlNode.getText(), subNameNode.getText(), subIconNode.getText());
                    menu.addSubMenu(subMenu);
                }
            }
            menus.add(menu);
        }
        this.menus = menus;
    }

    public List<Menu> getMenus() {
        return menus;
    }

    public static void main(String[] args) {
        MenuReader menuReader = MenuReader.getInstance();
        System.out.println(menuReader.getMenus());
    }
}
